package com.peanut.service.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
import org.springframework.stereotype.Service;

import com.peanut.StaticProperty;
import com.peanut.persistence.ResourceDaoIbatis;
import com.peanut.persistence.ResourceMapper;

/**
 * 
 * 此类在初始化时，应该取到所有资源及其对应角色的定义
 * 
 * @author Johan.Chenjh
 * 
 */
@Service
public class SecurityMetadataSourceImpl implements FilterInvocationSecurityMetadataSource {
	private UrlMatcher urlMatcher = new AntUrlPathMatcher();;

	public ResourceDaoIbatis resourceDaoIbatis;
	@Autowired
	public ResourceMapper resourceMapper;
	
	public void setResourceDao(ResourceDaoIbatis resourceDaoIbatis) {
		this.resourceDaoIbatis = resourceDaoIbatis;
	}

	public SecurityMetadataSourceImpl(ResourceDaoIbatis resourceDaoIbatis) {
		this.resourceDaoIbatis = resourceDaoIbatis;
		initResourceRoleMap();
		loadResourceDefine();
		//resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
	}
	
	private void initResourceRoleMap() {
		StaticProperty.resourceRoleMap = new HashMap<String, Collection<ConfigAttribute>>();
		Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
		ConfigAttribute ca1 = new SecurityConfig("ROLE_ADMIN");
		atts.add(ca1);
		ConfigAttribute ca2 = new SecurityConfig("ROLE_USER");
		atts.add(ca2);
		StaticProperty.resourceRoleMap.put("/main", atts);
		StaticProperty.resourceRoleMap.put("/admin/**", atts);
	}

	private void loadResourceDefine() {
		List<HashMap<String, String>> list = resourceDaoIbatis.queryUrlResourceWithRoleDao(null);
//		for (Resource res : list) {
//			Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
//			for (Role role : res.getRoles()) {
//				ConfigAttribute ca = new SecurityConfig(role.getName());
//				atts.add(ca);
//			}
//			if (res.getOpenView() != null) {
//				resourceMap.put(res.getOpenView(), atts);
//			}
//		}
		for (HashMap<String, String> res : list) {
			String path = res.get("OPEN_VIEW");
			Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
			for (HashMap<String, String> tempMap : list) {
				if (tempMap.get("OPEN_VIEW").equals(path)) {
					ConfigAttribute ca = new SecurityConfig(tempMap.get("ROLE_NAME"));
					atts.add(ca);
				}
			}
			if (res.get("OPEN_VIEW") != null) {
				StaticProperty.resourceRoleMap.put(res.get("OPEN_VIEW"), atts);
			}
		}
	}

	// According to a URL, Find out permission configuration of this URL.
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		// guess object is a URL.
		String url = ((FilterInvocation) object).getRequestUrl();
		int firstQuestionMarkIndex = url.indexOf("?");

        if (firstQuestionMarkIndex != -1) {
            url = url.substring(0, firstQuestionMarkIndex);
        }
		if (urlMatcher.requiresLowerCaseUrl()) {
            url = url.toLowerCase();
        }
		Iterator<String> ite = StaticProperty.resourceRoleMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			if (urlMatcher.pathMatchesUrl(resURL, url)) {
				return StaticProperty.resourceRoleMap.get(resURL);
			}
		}
		return null;
	}

	public boolean supports(Class<?> clazz) {
		return true;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

}
